#include "CTextField.h"
#include <iostream>
#include <cmath>
using namespace std;

// Variables specific to game
extern bool lockGame;


void TextField::CreateField(CFont & font_, unsigned x_, unsigned y_, unsigned width_, unsigned height_, unsigned max_lines_, bool text_wrap)
{
   font=&font_;
   on_off=1;
   this->text_wrap=text_wrap;
   x1=x_;
   y1=y_;
   width=width_;
   height=height_;
   max_lines=max_lines_;
   curr_line=0;
   char_width=10;
   char_height=16;
   border_thickness=2;
   padding = 5;
   x2=x1+char_width*width+padding*2;
   y2=y1-char_height*height-padding*2;
   text=new char*[max_lines];
   for(int i=0; i<max_lines;i++)
      text[i]=new char[width];
      
   text_color[0]=1.0;
   text_color[1]=1.0;
   text_color[2]=1.0;
   bg_color[0]=0.4;
   bg_color[1]=0.1;
   bg_color[2]=0.1;
   transparency=0.8;
   
   for(int i=0; i<max_lines;i++)
      text[i][0]='\0';
};

TextField::TextField(const TextField & text_field)
{
	font=text_field.font;
	on_off=text_field.on_off;
	x1=text_field.x1;
	y1=text_field.y1;
	width=text_field.width;
	height=text_field.height;
	max_lines=text_field.max_lines;
	curr_line=text_field.curr_line;
	char_width=text_field.char_width;
	char_height=text_field.char_height;
	border_thickness=text_field.border_thickness;
	padding=text_field.padding;
	text_wrap=text_field.text_wrap;
	x2=text_field.x2;
	y2=text_field.y2;
	text=new char*[max_lines];
	for(int i=0; i<max_lines;i++)
	{
		text[i]=new char[width];
		strcpy(text[i],text_field.text[i]);
	}

	text_color[0]=text_field.text_color[0];
	text_color[1]=text_field.text_color[1];
	text_color[2]=text_field.text_color[2];
	bg_color[0]=text_field.bg_color[0];
	bg_color[1]=text_field.bg_color[1];
	bg_color[2]=text_field.bg_color[2];
	transparency=text_field.transparency;
}



void TextField::Write(const char * text_, ...)
{
   if(text_==NULL)
      return;
     
   va_list list;
   va_start(list, text_);
     
   if(curr_line>=max_lines)
      curr_line=0;

	//if(text_wrap)	
	if(strlen(text_)>width+1)
	{
		char text2[2048];
		vsprintf(text2, text_, list); 
		unsigned char_index=0;		// keeps track of the remaining letters on the line
		unsigned char_index2=0;		// keeps track of the location in text
		unsigned word_length=0;
		int i=0;
		while(i<strlen(text2))
		{
			if(text2[i]==' ')
			{
				cout << " ";
				if(char_index2==width-1)
				{
					text[curr_line][width-1]='\0';
					if(curr_line==max_lines)
						curr_line=0;
					else
						curr_line++;
					char_index=0;
					char_index2=0;
				}
				if(char_index2!=0)
				{
					text[curr_line][char_index2]=text2[i];
					char_index++;
					char_index2++;
				}
				i++;
			}
			while(text2[i]!=' ' && i<strlen(text2))
			{
				if(word_length>width+1)
				{
					cout <<"UMMM...";
				}
				else if (word_length>width-char_index-1)
				{
					for(int j=char_index2;j<width;j++)
						text[curr_line][j-1]=' ';
					text[curr_line][width-1]='\0';
					curr_line++;
					if(curr_line==max_lines)
						curr_line=0;
					char_index=0;
					char_index2=0;
				}
				word_length++;
				char_index++;
				i++;
			}
			for(int h=0;h<word_length;h++)
			{
				cout << text2[i+h-word_length];
				text[curr_line][char_index2]=text2[i+h-word_length];
				char_index2++;
			}
			cout << word_length;
			word_length=0;
		}
		for(int j=char_index2; j<width;j++)
			text[curr_line][j]=' ';
		text[curr_line][width-1]='\0';
		curr_line++;
		if(curr_line==max_lines)
			curr_line=0;
	}
   
	//else if(!text_wrap)

	if(strlen(text_)<=width+1)
	{
		vsprintf(text[curr_line], text_, list); 
		curr_line++;
	}
	va_end(list);
};

void TextField::Draw(void)
{
   if(!on_off)
      return;
   glMatrixMode(GL_PROJECTION);
   glPushMatrix();
   glLoadIdentity();
   gluOrtho2D(0,1440,0,900);   // >>> feed screen width and height
   glMatrixMode(GL_MODELVIEW);
   glDisable(GL_DEPTH_TEST);
   glEnable(GL_BLEND);
   glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);
   // box
      // outline border
      glLoadIdentity();
      glColor3f(1,1,1);
      glLineWidth(border_thickness);
      glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
      glBegin(GL_QUADS);
      glVertex2i(x1,y1);
      glVertex2i(x2,y1);
      glVertex2i(x2,y2);
      glVertex2i(x1,y2);
      glEnd();
   glColor4f(bg_color[0],bg_color[1],bg_color[2],transparency);
   glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
   glBegin(GL_QUADS);
   glVertex2i(x1,y1);
   glVertex2i(x2,y1);
   glVertex2i(x2,y2);
   glVertex2i(x1,y2);
   glEnd();

   //glPopMatrix();

   // text
   glColor3f(text_color[0],text_color[1],text_color[2]);
   
   int i=0;
   while(i<max_lines && text[i][0]!='/0')
   {
      font->glPrint(x1+padding,y1-(i+1)*(char_height)-padding,text[i],NULL);
      i++;
   }
   //cout<<text[2]<<"kj";
   glMatrixMode(GL_PROJECTION);
   glPopMatrix();
   glMatrixMode(GL_MODELVIEW);
   glEnable(GL_DEPTH_TEST);
};

void TextField::SetBGColor(float val1, float val2, float val3)
{
   bg_color[0]=val1;
   bg_color[1]=val2;
   bg_color[2]=val3;
};

TextField & TextField::operator=(const TextField & text_field)
{
	font=text_field.font;
	on_off=text_field.on_off;
	x1=text_field.x1;
	y1=text_field.y1;
	width=text_field.width;
	height=text_field.height;
	max_lines=text_field.max_lines;
	curr_line=text_field.curr_line;
	char_width=text_field.char_width;
	char_height=text_field.char_height;
	border_thickness=text_field.border_thickness;
	padding=text_field.padding;
	text_wrap=text_field.text_wrap;
	x2=text_field.x2;
	y2=text_field.y2;
	text=new char*[max_lines];
	for(int i=0; i<max_lines;i++)
	{
		text[i]=new char[width];
		strcpy(text[i],text_field.text[i]);
	}
	text_color[0]=text_field.text_color[0];
	text_color[1]=text_field.text_color[1];
	text_color[2]=text_field.text_color[2];
	bg_color[0]=text_field.bg_color[0];
	bg_color[1]=text_field.bg_color[1];
	bg_color[2]=text_field.bg_color[2];
	transparency=text_field.transparency;
   
	return *this;
}

TextField::~TextField()
{
   delete [] text;
};


/////////////////////////////////////////////////////////////////////
// TextField Manager
/////////////////////////////////////////////////////////////////////

void TextFieldManager::draw()
{
	if(on_off)
		text_fields[currentIndex].Draw();
}

void TextFieldManager::addTextField(TextField textField)
{
		text_fields.push_back(textField);
}

bool TextFieldManager::removeTextField(unsigned index)
{
	if(index<text_fields.size())
	{
		text_fields.erase(text_fields.begin() + index - 1);
		return 1;
	}
	else return 0;
}

bool TextFieldManager::nextField(void)
{
	if(currentIndex+1<text_fields.size())
	{
		currentIndex++;
		return 1;
	}
	else 
	{
		setState(0);
		lockGame=0;
		return 0;
	}
}
